package com.iamk.util;

import ij.process.ColorProcessor;

import java.awt.Color;
import java.awt.Image;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class CreateImageRegion {
	
	public String imgPath;
	public String maskPath;
	public List<Integer> listLabel;
	
	public List<Image> listRegion;
	List<Integer> listRegionLabel;
	
	ColorProcessor image;
	
	int[][] mask;
	int maxRegion;
	int width;
	int height;
	
	public CreateImageRegion(String imgPath,String maskPath) {
		this.imgPath = imgPath;
		this.maskPath = maskPath;
		this.listRegion = new ArrayList<Image>();
		this.listLabel = new ArrayList<Integer>();
		this.listRegionLabel = new ArrayList<Integer>();
	}
	
	public CreateImageRegion(String imgPath,int[][] mask){
		this.imgPath = imgPath;
		this.mask = mask;
		this.listRegion = new ArrayList<Image>();
		this.listLabel = new ArrayList<Integer>();
		this.listRegionLabel = new ArrayList<Integer>();
	}
	
	public void loadData(String imgPath,String maskPath){
		try {
			BufferedImage img = ImageUtil.readImage(imgPath);
			int[] imgPixels = ImageUtil.convertToPixels(img);
			int[] imgPixelsResize = ImageUtil.resizeBilinear(imgPixels, img.getWidth(), img.getHeight(), ImageUtil.IMG_WIDTH, ImageUtil.IMG_HEIGHT);
			BufferedImage imgResize = ImageUtil.getImageFromArray(imgPixelsResize, ImageUtil.IMG_WIDTH, ImageUtil.IMG_HEIGHT);
	        image = new ColorProcessor(imgResize);
	        mask = GetData.readMaskFile(maskPath);
	    	height = img.getHeight();
			width = img.getWidth();
			listRegionLabel = getListRegion(mask);
			// Get region
			for(int i = 0; i < listRegionLabel.size(); i++){
				// Create image region
				int numTotal = 0;
				int totalRed = 0;
				int totalGreen = 0;
				int totalBlue = 0;
				List<Integer> mListX = new ArrayList<Integer>();  
				List<Integer> mListY = new ArrayList<Integer>();  
				BufferedImage regioni = new BufferedImage(width, height, ColorSpace.TYPE_RGB);
				
				for(int r = 0; r < height; r++ ){
					for(int c = 0; c < width; c++){
						if(mask[r][c] == listRegionLabel.get(i)){
							// Add to variate for calculate average color
							int mColor = img.getRGB(c, r);
					        numTotal++;
					        totalRed += mColor >>16 & 0xff;
					        totalGreen += mColor >>8 & 0xff;
					        totalBlue += mColor & 0xff;
					        					        
					        // Set pixel region
							regioni.setRGB(c, r, mColor);
							mListX.add(r);
							mListY.add(c);
						}
					}
				}
				// Replace by average color
				for(int r = 0; r < height; r++ ){
					for(int c = 0; c < width; c++){
						if(mask[r][c] != listRegionLabel.get(i)){
							regioni.setRGB(c, r, (new Color(totalRed/numTotal, 
	                				   totalGreen/numTotal,
	                				   totalBlue/numTotal).getRGB()));
						}
					}
				}
				
				// Crop image region
				int minR = getMin(convertToArray(mListX));
				int maxR = getMax(convertToArray(mListX));
				int minC = getMin(convertToArray(mListY));
				int maxC = getMax(convertToArray(mListY));
				int subW = (maxC-minC);
				int subH = (maxR-minR);
//				System.out.println("Region " + i);
//				System.out.println(width + "/" + height);
//				System.out.println("min: " + minR + "/" + minC);
//				System.out.println("size: " + subH + "/" + subW);
				if(subW > 0 && subH > 0){
					// Check size of subIMG
					if(subW > 64 && subH > 64){
//						File outputfile1 = new File("D:/workspace-thesis/IAMK/region/region_origin1_"+ String.valueOf(i) + ".png");
//						ImageIO.write(regioni, "png", outputfile1);
						
						BufferedImage subIMG = ImageUtil.deepCopy(regioni).getSubimage(minC, minR, subW, subH);
						subIMG = ImageUtil.resizeImage(subIMG);
						
						// Add image region into list
//						File outputfile = new File("D:/workspace-thesis/IAMK/region/region1_"+ String.valueOf(i) + ".png");
//						ImageIO.write(subIMG, "png", outputfile);
						
						listRegion.add(regioni);
						listLabel.add(listRegionLabel.get(i));
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void loadData(String imgPath){
		try {
			BufferedImage img = ImageUtil.readImage(imgPath);
	        image = new ColorProcessor(img);
	    	height = img.getHeight();
			width = img.getWidth();
			listRegionLabel = getListRegion(mask);
			// Get region
			System.out.println("[" + height + "," + width + "][" + mask.length + "," + mask[0].length + "]");
			for(int i = 0; i < listRegionLabel.size(); i++){
				// Create image region
				int numTotal = 0;
				int totalRed = 0;
				int totalGreen = 0;
				int totalBlue = 0;
				List<Integer> mListX = new ArrayList<Integer>();  
				List<Integer> mListY = new ArrayList<Integer>();  
				BufferedImage regioni = new BufferedImage(width, height, ColorSpace.TYPE_RGB);
				
				for(int r = 0; r < height; r++ ){
					for(int c = 0; c < width; c++){
						if(mask[r][c] == listRegionLabel.get(i)){
							// Add to variate for calculate average color
							int mColor = img.getRGB(c, r);
					        numTotal++;
					        totalRed += mColor >>16 & 0xff;
					        totalGreen += mColor >>8 & 0xff;
					        totalBlue += mColor & 0xff;
					        					        
					        // Set pixel region
							regioni.setRGB(c, r, mColor);
							mListX.add(r);
							mListY.add(c);
						}
					}
				}
				// Replace by average color
				for(int r = 0; r < height; r++ ){
					for(int c = 0; c < width; c++){
						if(mask[r][c] != listRegionLabel.get(i)){
							regioni.setRGB(c, r, (new Color(totalRed/numTotal, 
	                				   totalGreen/numTotal,
	                				   totalBlue/numTotal).getRGB()));
						}
					}
				}
				
				// Crop image region
				int minR = getMin(convertToArray(mListX));
				int maxR = getMax(convertToArray(mListX));
				int minC = getMin(convertToArray(mListY));
				int maxC = getMax(convertToArray(mListY));
				int subW = (maxC-minC);
				int subH = (maxR-minR);
//				System.out.println("Region " + i);
//				System.out.println(width + "/" + height);
//				System.out.println("min: " + minR + "/" + minC);
//				System.out.println("size: " + subH + "/" + subW);
				if(subW > 0 && subH > 0){
					// Check size of subIMG
					if(subW > 64 && subH > 64){
//						File outputfile1 = new File("D:/workspace-thesis/IAMK/region/region_origin1_"+ String.valueOf(i) + ".png");
//						ImageIO.write(regioni, "png", outputfile1);
						
						BufferedImage subIMG = ImageUtil.deepCopy(regioni).getSubimage(minC, minR, subW, subH);
						subIMG = ImageUtil.resizeImage(subIMG);
						
						// Add image region into list
//						File outputfile = new File("D:/workspace-thesis/IAMK/region/region1_"+ String.valueOf(i) + ".png");
//						ImageIO.write(subIMG, "png", outputfile);
						
						listRegion.add(regioni);
//						listLabel.add(listRegionLabel.get(i));
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public int getMax(int[] mListIdx){
		int max = -1;
		for(int i = 0; i < mListIdx.length; i++){
			if(max < mListIdx[i])
				max = mListIdx[i];
		}
		return max;
	}
	
	public int getMin(int[] mListIdx){
		int min = 999999;
		for(int i = 0; i < mListIdx.length; i++){
			if(min > mListIdx[i])
				min = mListIdx[i];
		}
		return min;
	}
	
	public int[] convertToArray(List<Integer> data){
		int[] arr = new int[data.size()];
		for(int i = 0; i < data.size(); i++){
			arr[i] = data.get(i);
		}
		return arr;
	}
	
	public List<Integer> getListRegion(int[][] mask){
		List<Integer> mRegion = new ArrayList<Integer>();
		for (int i = 0; i < mask.length; i++){
			for (int j = 0; j < mask[0].length; j++) {
				if(mask[i][j] != -1){
					if (!mRegion.contains(mask[i][j])) {
						mRegion.add(mask[i][j]);
					}
				}
			}
		}
		return mRegion;
	}
}
